﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace SpiritEngine
{
    // This is the Spirit Engine Content Manager class
    public class SE_ContentManager : ContentManager
    {
        // MEMBER VARIABLES
        // ------------------------------------------------------------------------------------------------------------------------

        // Cache of all the loaded content
        Dictionary<string, object> m_dictLoadedAssets = new Dictionary<string, object>();
        List<IDisposable> m_listDisposableAssets = new List<IDisposable>();


        // CONSTRUCTORS
        // ------------------------------------------------------------------------------------------------------------------------

        public SE_ContentManager(IServiceProvider services)
            : base(services)
        {
        } // end SE_ContentManager::SE_ContentManager(IServiceProvider)

        public SE_ContentManager(IServiceProvider services, string strRootDirectory)
            : base(services, strRootDirectory)
        {
        } // end SE_ContentManager::SE_ContentManager(IServiceProvider, string)


        // PRIVATE/PROTECTED METHODS
        // ------------------------------------------------------------------------------------------------------------------------



        // METHODS
        // ------------------------------------------------------------------------------------------------------------------------

        // Load an asset and cache it
        public override T Load<T>(string strAssetName)
        {
            // Return the stored instance of the asset if there is one.
            if (m_dictLoadedAssets.ContainsKey(strAssetName))
                return (T)m_dictLoadedAssets[strAssetName];

            // If there isn't an instance of this asset already in our asset cache,
            // then load an instance of it into our asset cache.
            T read = base.ReadAsset<T>(strAssetName, RecordDisposableAsset);
            m_dictLoadedAssets.Add(strAssetName, read);

            // Now that we have an instance of this asset loaded, return it.
            return read;

        } // end T SE_ContentManager::Load<T>(string)

        void RecordDisposableAsset(IDisposable disposable)
        {
            m_listDisposableAssets.Add(disposable);

        } // end void SE_ContentManager::RecordDisposableAsset(IDisposable)

        public T LoadFreshCopy<T>(string strAssetName)
        {
            return base.ReadAsset<T>(strAssetName, null);

        } // end T SE_ContentManager::LoadFreshCopy<T>(string)

        // Unload a single specified asset
        public void UnloadAsset(string strAssetName)
        {
            if (m_dictLoadedAssets.ContainsKey(strAssetName))
            {
                if (m_dictLoadedAssets[strAssetName] is IDisposable &&
                    m_listDisposableAssets.Contains((IDisposable)m_dictLoadedAssets[strAssetName]))
                {
                    IDisposable disposable = (IDisposable)m_dictLoadedAssets[strAssetName];
                    
                    m_listDisposableAssets.Remove(disposable);
                    
                    disposable.Dispose();
                }

                m_dictLoadedAssets.Remove(strAssetName);
            }

        } // end void SE_ContentManager::UnloadAsset(string)

        // This function unloads all assets that are currently stored in our asset cache.
        public override void Unload()
        {
            foreach (IDisposable disposable in m_listDisposableAssets)
                disposable.Dispose();

            m_dictLoadedAssets.Clear();
            m_listDisposableAssets.Clear();

        } // end void SE_ContentManager::Unload();



        // DEBUG METHODS
        // ------------------------------------------------------------------------------------------------------------------------

#if (DEBUG)
        // put all debug methods in here...
#endif



        // PROPERTIES
        // ------------------------------------------------------------------------------------------------------------------------



        // EVENTS
        // ------------------------------------------------------------------------------------------------------------------------



    } // end class SE_ContentManager
}
